package com.shaozi.nc.configuration;

import java.sql.SQLException;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.orm.hibernate4.HibernateTemplate;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.util.StringUtils;
import com.shaozi.data.hib.dao.CommDaoSupport;

/**
 * hibernate 配置
 * 
 * @author lyx
 *
 */
@Configuration
public class DruidDBConfiguration {

	private Logger logger = Logger.getLogger(DruidDBConfiguration.class);

	@Value("${jdbc.url}")
	private String dbUrl;

	@Value("${jdbc.user}")
	private String username;

	@Value("${jdbc.password}")
	private String password;

	@Value("${jdbc.driverClass}")
	private String driverClassName;

	@Value("${jdbc.initialPoolSize}")
	private int initialSize;

	@Value("${jdbc.minIdle}")
	private int minIdle;

	@Value("${jdbc.maxActive}")
	private int maxActive;

	@Value("${jdbc.maxWaitTime}")
	private int maxWait;

	// @Value("${spring.datasource.timeBetweenEvictionRunsMillis}")
	// private int timeBetweenEvictionRunsMillis;

	// @Value("${spring.datasource.minEvictableIdleTimeMillis}")
	// private int minEvictableIdleTimeMillis;

	@Value("${jdbc.datasource.validationQuery}")
	private String validationQuery;

	@Value("${jdbc.testWhileIdle}")
	private boolean testWhileIdle;

	@Value("${jdbc.testOnBorrow}")
	private boolean testOnBorrow;

	// @Value("${spring.datasource.testOnReturn}")
	// private boolean testOnReturn;

	// @Value("${spring.datasource.poolPreparedStatements}")
	// private boolean poolPreparedStatements;

	// @Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}")
	// private int maxPoolPreparedStatementPerConnectionSize;

	@Value("${jdbc.datasource.filters:#{null}}")
	private String filters;

	@Value("${jdbc.datasource.connectionProperties:#{null}}")
	private String connectionProperties;

	@Value("${hibernate.dialect:org.hibernate.dialect.MySQLDialect}")
	private String hibernateDialect;
	@Value("${hibernate.show_sql}")
	private String hibernateShowSql;
	@Value("${hibernate.format_sql}")
	private String hibrenateFormatSql;
	@Value("${hibernate.fetch_size}")
	private String hibernateFetchSize;
	@Value("${hibernate.batch_size}")
	private String hibernateBatchSize;

	@Value("${hibernate.package.to.scan:com.shaozi}")
	private String hibernatePackagesToScan;
	// @Autowired
	// private SessionFactory sessionFactory;

	@Bean // 声明其为Bean实例
	@Primary // 在同样的DataSource中，首先使用被标注的DataSource
	public DataSource dataSource() {
		DruidDataSource datasource = new DruidDataSource();

		datasource.setUrl(this.dbUrl);
		datasource.setUsername(username);
		datasource.setPassword(password);
		datasource.setDriverClassName(driverClassName);

		// configuration
		datasource.setInitialSize(initialSize);
		datasource.setMinIdle(minIdle);
		datasource.setMaxActive(maxActive);
		datasource.setMaxWait(maxWait);
		// datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
		// datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
		datasource.setValidationQuery(validationQuery);
		datasource.setTestWhileIdle(testWhileIdle);
		datasource.setTestOnBorrow(testOnBorrow);
		// datasource.setTestOnReturn(testOnReturn);
		// datasource.setPoolPreparedStatements(poolPreparedStatements);
		// datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
		if (!StringUtils.isEmpty(filters)) {
			try {
				datasource.setFilters(filters);
			} catch (SQLException e) {
				logger.error(e.getMessage(), e);
			}
		}
		if (!StringUtils.isEmpty(connectionProperties)) {
			datasource.setConnectionProperties(connectionProperties);
		}
		return datasource;
	}

	@Bean("sessionFactory")
	public LocalSessionFactoryBean sessionFactory(DataSource dataSource) {
		LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
		sessionFactory.setDataSource(dataSource);
		Properties hibernateProperties = new Properties();
		hibernateProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
		hibernateProperties.setProperty("hibernate.show_sql", hibernateShowSql);
		hibernateProperties.setProperty("hibernate.format_sql", hibrenateFormatSql);
		hibernateProperties.setProperty("hibernate.fetch_size", hibernateFetchSize);
		hibernateProperties.setProperty("hibernate.batch_size", hibernateBatchSize);
		sessionFactory.setHibernateProperties(hibernateProperties);
		sessionFactory.setPackagesToScan(hibernatePackagesToScan);
		return sessionFactory;
	}

	@Bean
	public HibernateTemplate hibernateTemplate(LocalSessionFactoryBean sessionFactory) {
		HibernateTemplate hibernateTemplate = new HibernateTemplate();
		hibernateTemplate.setSessionFactory(sessionFactory.getObject());
		return hibernateTemplate;
	}

	@Bean
	public CommDaoSupport commDaoSupport(HibernateTemplate hibernateTemplate) {
		CommDaoSupport commDaoSupport = new CommDaoSupport();
		commDaoSupport.setHibernateTemplate(hibernateTemplate);
		return commDaoSupport;
	}

	/**
	 * 事物开启
	 * 
	 * @return
	 */
	@Bean("transactionManager")
	public HibernateTransactionManager transactionManager(LocalSessionFactoryBean sessionFactory) {
		HibernateTransactionManager transactionManager = new HibernateTransactionManager();
		transactionManager.setSessionFactory(sessionFactory.getObject());
		return transactionManager;
	}

	// @Bean
	// public PlatformTransactionManager txManager(DataSource dataSource) {
	// return new DataSourceTransactionManager(dataSource);
	// }
}
